unit Medax1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, Menus, ExtCtrls, Buttons, Tabs, StdCtrls, IniFiles, Grids,
  DBGrids, DB, DBTables, DBCtrls, ShapeBox, MedaxData, MedaObjects;

type
  TMainForm = class(TForm)
    StatusBar: TStatusBar;
    DrawPopUpMenu: TPopupMenu;
    N1: TMenuItem;
    DrawPopUpcancel: TMenuItem;
    PCBPopupMenu: TPopupMenu;
    N2: TMenuItem;
    PCBPopUpCancel: TMenuItem;
    DBPanel: TPanel;
    FamiliesPanel: TPanel;
    PartsPanel: TPanel;
    PartsDBGrid: TDBGrid;
    FamiliesDBGrid: TDBGrid;
    MainPanel: TPanel;
    ListPanel: TPanel;
    PartsTreeView: TTreeView;
    PartsDBNavigator: TDBNavigator;
    FamiliesDBNavigator: TDBNavigator;
    TabControl: TTabControl;
    MainToolsPanel: TPanel;
    PartsButton: TSpeedButton;
    SpeedButton1: TSpeedButton;
    TreeButton: TSpeedButton;
    ZoomInBtn: TSpeedButton;
    ZoomOutBtn: TSpeedButton;
    CloseBtn: TBitBtn;
    PCBToolsPanel: TPanel;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    SpeedButton5: TSpeedButton;
    SpeedButton6: TSpeedButton;
    SpeedButton9: TSpeedButton;
    SpeedButton10: TSpeedButton;
    SpeedButton11: TSpeedButton;
    SpeedButton12: TSpeedButton;
    SpeedButton13: TSpeedButton;
    SpeedButton14: TSpeedButton;
    SpeedButton15: TSpeedButton;
    SpeedButton16: TSpeedButton;
    SplitPanel: TPanel;
    MainClientPanel: TPanel;
    MainDrawPanel: TPanel;
    DrawPaintBox: TPaintBox;
    MainPCBPanel: TPanel;
    PCBPaintBox: TPaintBox;
    MainMechPanel: TPanel;
    MainGerberPanel: TPanel;
    MainBoxPanel: TPanel;
    BoxPaintBox: TPaintBox;
    BoxPanel: TPanel;
    BoxDBPanel: TPanel;
    BoxDBGrid: TDBGrid;
    BoxDBNavigator: TDBNavigator;
    PinsSplitPanel: TPanel;
    PinsDBPanel: TPanel;
    PinsDBGrid: TDBGrid;
    PinsDBNavigator: TDBNavigator;
    MainShapePanel: TPanel;
    ShapeBox: TShapeBox;
    ShapePanel: TPanel;
    PadsGridPanel: TPanel;
    PadsDBNavigator: TDBNavigator;
    PadsDBGrid: TDBGrid;
    ShapeGridPanel: TPanel;
    ShapeDBGrid: TDBGrid;
    ShapeDBNavigator: TDBNavigator;
    BoxToolsPanel: TPanel;
    BoxOpenFileBtn: TSpeedButton;
    BoxOpenDialog: TOpenDialog;
    ShapeToolsPanel: TPanel;
    ShpaeOpenFileBtn: TSpeedButton;
    DrawToolsPanel: TPanel;
    MechToolsPanel: TPanel;
    GerberToolsPanel: TPanel;
    SpeedButton2: TSpeedButton;
    SpeedButton7: TSpeedButton;
    SpeedButton8: TSpeedButton;
    SpeedButton17: TSpeedButton;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    Panel5: TPanel;
    Panel4: TPanel;
    Panel6: TPanel;
    Panel7: TPanel;
    Panel8: TPanel;
    MainProjectPanel: TPanel;
    ProjectToolsPanel: TPanel;
    SpeedButton18: TSpeedButton;
    SpeedButton19: TSpeedButton;
    SpeedButton20: TSpeedButton;
    PCBColorDialog: TColorDialog;
    ProgressPanel: TPanel;
    ProgressBarHigh: TProgressBar;
    ProgressBarLow: TProgressBar;
    procedure PCBPaintBoxPaint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure FamiliesDataSourceDataChange(Sender: TObject; Field: TField);
    procedure DrawPaintBoxPaint(Sender: TObject);
    procedure CloseBtnClick(Sender: TObject);
    procedure ZoomInBtnClick(Sender: TObject);
    procedure ZoomOutBtnClick(Sender: TObject);
    procedure PartsTableNewRecord(DataSet: TDataSet);
    procedure DrawPaintBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure DrawPaintBoxMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ShapeBoxPaint(Sender: TObject);
    procedure ShapeDataSourceDataChange(Sender: TObject; Field: TField);
    procedure PartsButtonClick(Sender: TObject);
    procedure TreeButtonClick(Sender: TObject);
    procedure PadsTableAfterPost(DataSet: TDataSet);
    procedure TabControlChange(Sender: TObject);
    procedure SplitPanelMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure PinsSplitPanelMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure BoxPaintBoxPaint(Sender: TObject);
    procedure BoxDataSourceDataChange(Sender: TObject; Field: TField);
    procedure PinsTableAfterPost(DataSet: TDataSet);
    procedure BoxOpenFileBtnClick(Sender: TObject);
    procedure BoxTableBeforeDelete(DataSet: TDataSet);
    procedure FamiliesTableBeforeDelete(DataSet: TDataSet);
    procedure Panel1Click(Sender: TObject);
  private
    { Private declarations }
    PCBSymbols : TBitmap ;
    DrawSymbols : TBitmap ;
  public
    { Public declarations }
  end ;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

procedure TMainForm.FormCreate(Sender: TObject);
begin
	PCBSymbols := TBitmap.Create ;
	PCBSymbols.LoadFromFile('c:\Medax\Bitmaps\PCB16.bmp') ;
	DrawSymbols := TBitmap.Create ;
   DrawSymbols.LoadFromFile( 'c:\Medax\Bitmaps\DRAW20.bmp' ) ;
end;

procedure TMainForm.FormActivate(Sender: TObject);
var IniFile : TIniFile ;
begin
	if Tag = 0 then begin
   	Tag := 1 ;
       MainProjectPanel.Align := alClient ;
       MainDrawPanel.Align := alClient ;
   	MainPCBPanel.Align := alClient ;
   	MainMechPanel.Align := alClient ;
   	MainGerberPanel.Align := alClient ;
   	MainBoxPanel.Align := alClient ;
		MainShapePanel.Align := alClient ;
		IniFile := TIniFile.Create( 'c:\Windows\Meda.Ini' ) ;
		// get preferences
		IniFile.Free ;
       // open databases
       with MedaxDataForm do begin
	       FamiliesTable.Active := True ;
   	    PartsTable.Active := True ;
       	ShapeTable.Active := True ;
	       PadsTable.Active := True ;
			BoxTable.Active := True ;
			PinsTable.Active := True ;
           FamiliesDataSourceDataChange( nil, nil ) ;
		end ;
   	MainProjectPanel.Visible := True ;
       ProjectToolsPanel.Visible := MainProjectPanel.Visible ;
   end ;
end;

procedure TMainForm.CloseBtnClick(Sender: TObject);
begin
	Close ;
end;

procedure TMainForm.FamiliesDataSourceDataChange(Sender: TObject;
  Field: TField);
	var sText : string ;
begin
	with MedaxDataForm do begin
		sText := FamiliesTable.FindField( 'Family' ).AsString ;
		if PartsTable.Active then
			PartsTable.SetRange( [ sText], [ sText] ) ;
   end ;
end;

procedure TMainForm.DrawPaintBoxPaint(Sender: TObject);
var Rect : TRect ;
begin
	with DrawPaintBox do begin
		SetRect( Rect,
   		(Width div 2) - (Tag * DrawSymbols.Width div 16),
   		(Height div 2) - (Tag * DrawSymbols.Height div 16),
			(Width div 2) + (Tag * DrawSymbols.Width div 16),
   		(Height div 2) + (Tag * DrawSymbols.Height div 16)
	   ) ;
     Canvas.StretchDraw( Rect, DrawSymbols ) ;
   end ;
end;

procedure TMainForm.PCBPaintBoxPaint(Sender: TObject);
var Rect : TRect ;
begin
	with PCBPaintBox do begin
		SetRect( Rect,
			(Width div 2) - (Tag * PCBSymbols.Width div 16),
			(Height div 2) - (Tag * PCBSymbols.Height div 16),
			(Width div 2) + (Tag * PCBSymbols.Width div 16),
			(Height div 2) + (Tag * PCBSymbols.Height div 16)
		) ;
		Canvas.StretchDraw( Rect, PCBSymbols ) ;
	end ;
end;

procedure TMainForm.ZoomInBtnClick(Sender: TObject);
begin
	if MainDrawPanel.Visible then begin
   	with DrawPaintBox do begin
			if Tag < 32 then
				Tag := Tag * 2 ;
       	Invalidate ;
       end ;
   end else if MainPCBPanel.Visible then begin
   	with PCBPaintBox do begin
			if Tag < 32 then
				Tag := Tag * 2 ;
       	Invalidate ;
       end ;
   end else if MainBoxPanel.Visible then begin
   	with BoxPaintBox do begin
			if Tag < 32 then
				Tag := Tag * 2 ;
       	Invalidate ;
       end ;
   end else if MainShapePanel.Visible then begin
   	with ShapeBox do begin
			if ShapeBox.Tag < 32 then
				Tag := Tag * 2 ;
       	Invalidate ;
       end ;
  end
end;

procedure TMainForm.ZoomOutBtnClick(Sender: TObject);
begin
	if MainDrawPanel.Visible then
   	with DrawPaintBox do begin
			if Tag > 4 then
				Tag := Tag div 2 ;
       	Invalidate ;
       end
	else if MainPCBPanel.Visible then
   	with PCBPaintBox do begin
			if Tag > 4 then
				Tag := Tag div 2 ;
       	Invalidate ;
       end
	else if MainBoxPanel.Visible then
   	with BoxPaintBox do begin
			if Tag > 16 then
				Tag := Tag div 2 ;
       	Invalidate ;
       end
	else if MainShapePanel.Visible then
   	with ShapeBox do begin
			if Tag > 4 then
				Tag := Tag div 2 ;
       	Invalidate ;
       end
end;

procedure TMainForm.PartsTableNewRecord(DataSet: TDataSet);
begin
	with MedaxDataForm do
		PartsTable.FindField('Family').AsString := FamiliesTable.FindField('Family').AsString ;
end;

procedure TMainForm.DrawPaintBoxMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
   StatusBar.Panels[ 1 ].Text := IntToStr( X ) ;
   StatusBar.Panels[ 2 ].Text := IntToStr( Y ) ;
   StatusBar.Update ;
end;

procedure TMainForm.DrawPaintBoxMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
   if Shift = [ssMiddle] then begin
   	DrawPaintBox.Tag := DrawPaintBox.Tag * 2 ;
       DrawPaintBox.Invalidate ;
   end ;
end;

procedure TMainForm.ShapeBoxPaint(Sender: TObject);
var
	sShape, sPad : string ;
   n, nPins, nPinSpacing, nRowSpacing, nColumnSpacing : integer ;
	nPadWidth, nPadHeight, nHoleSize : integer ;
	nBoxWidth, nBoxHeight : integer ;
   nXOrg, nYOrg, nZoom : integer ;
begin
	nXOrg := ShapeBox.Width div 2 ;
   nYOrg := ShapeBox.Height div 2 ;
   nZoom := ShapeBox.Tag ;
	with MedaxDataForm.ShapeTable do begin
   	try
	   		sShape := FindField( 'Type' ).AsString ;
			nPins := FindField( 'Pins' ).AsInteger ;
			sPad := FindField( 'Pad' ).AsString ;
			nPinSpacing := FindField( 'PinSpacing' ).AsInteger * nZoom ;
			nRowSpacing := FindField( 'RowSpacing' ).AsInteger * nZoom div 32 ;
			nColumnSpacing := FindField( 'ColumnSpacing' ).AsInteger * nZoom div 32 ;
			nBoxHeight := FindField( 'BoxHeight' ).AsInteger * nZoom div 64 ;
			nBoxWidth := FindField( 'BoxWidth' ).AsInteger * nZoom div 64 ;
       except
       	Exit ;
       end ;
   end ;
	with MedaxDataForm.PadsTable do begin
   	try
			FindKey( [ sPad ] ) ;
			nPadHeight := FindField( 'TopPadHeight' ).AsInteger * nZoom div 64 ;
			nPadWidth := FindField( 'TopPadWidth' ).AsInteger * nZoom div 64 ;
			nHoleSize := FindField( 'HoleSize' ).AsInteger * nZoom div 64 ;
       except
       	Exit ;
       end ;
   end ;
   with ShapeBox.Canvas do begin
       Brush.Color := clWhite ;
       Pen.Color := clBlack ;
  		Rectangle( nXOrg - nBoxWidth, nYOrg - nBoxHeight, nXOrg + nBoxWidth, nYOrg + nBoxHeight ) ;
       MoveTo( nXOrg, 0 ) ;
  		LineTo( nXOrg, ShapeBox.Height ) ;
       MoveTo( 0, nYOrg ) ;
  		LineTo( ShapeBox.Width, nYOrg ) ;
       Brush.Color := clBlack ;
       Pen.Color := clBlack ;
		Font.Color := clTeal ;
		if LowerCase( sShape ) = 'so' then begin
          	Rectangle( nXOrg - nPadWidth - nColumnSpacing div 2, nYOrg - nPadHeight, nXOrg + nPadWidth - nColumnSpacing div 2 + 1, nYOrg + nPadHeight + 1 ) ;
		  	Rectangle( nXOrg - nPadWidth + nColumnSpacing div 2, nYOrg - nPadHeight, nXOrg + nPadWidth + nColumnSpacing div 2 + 1, nYOrg + nPadHeight + 1 ) ;
		end else if LowerCase( sShape ) = 'dil' then begin
       	for n := 0 to nPins div 2 - 1 do begin
       		nXOrg := ShapeBox.Width div 2 + ( n * nPinSpacing - ( nPins div 2 - 1 ) * nPinSpacing div 2 ) div 32000 ;
				Brush.Color := clBlack ;
				Brush.Style := bsSolid ;
           	Ellipse( nXOrg - nPadWidth, nYOrg - nPadWidth - nRowSpacing div 2, nXOrg + nPadWidth + 1, nYOrg + nPadWidth - nRowSpacing div 2 + 1 ) ;
			  	Ellipse( nXOrg - nPadWidth, nYOrg - nPadWidth + nRowSpacing div 2, nXOrg + nPadWidth + 1, nYOrg + nPadWidth + nRowSpacing div 2 + 1 ) ;
				Brush.Color := clSilver ;
           	Ellipse( nXOrg - nHoleSize, nYOrg - nHoleSize - nRowSpacing div 2, nXOrg + nHoleSize + 1, nYOrg + nHoleSize - nRowSpacing div 2 + 1 ) ;
			  	Ellipse( nXOrg - nHoleSize, nYOrg - nHoleSize + nRowSpacing div 2, nXOrg + nHoleSize + 1, nYOrg + nHoleSize + nRowSpacing div 2 + 1 ) ;
				Brush.Style := bsClear ;
           	TextOut( nXOrg + nPadWidth, nYOrg + nPadWidth + nRowSpacing div 2, IntToStr( n + 1 ) ) ;
               TextOut( nXOrg + nPadWidth, nYOrg + nPadWidth - nRowSpacing div 2, IntToStr( nPins - n ) ) ;
           end ;
		end else if ( LowerCase( sShape ) = 'qfp' ) or ( LowerCase( sShape ) = 'plcc' ) then begin
 			nYOrg := ShapeBox.Height div 2 ;
 			Brush.Color := clBlack ;
	   		Brush.Style := bsSolid ;
       	for n := 0 to nPins div 4 - 1 do begin
       		nXOrg := ShapeBox.Width div 2 + ( n * nPinSpacing - ( nPins div 4 - 1 ) * nPinSpacing div 2 ) div 32000 ;
           	Rectangle( nXOrg - nPadWidth, nYOrg - nPadHeight - nRowSpacing div 2, nXOrg + nPadWidth + 1, nYOrg + nPadHeight - nRowSpacing div 2 + 1 ) ;
			  	Rectangle( nXOrg - nPadWidth, nYOrg - nPadHeight + nRowSpacing div 2, nXOrg + nPadWidth + 1, nYOrg + nPadHeight + nRowSpacing div 2 + 1 ) ;
           end ;
 			nXOrg := ShapeBox.Width div 2 ;
   	   	for n := 0 to nPins div 4 - 1 do begin
       		nYOrg := ShapeBox.Height div 2 + ( n * nPinSpacing - ( nPins div 4 - 1 ) * nPinSpacing div 2 ) div 32000 ;
				Brush.Color := clBlack ;
				Brush.Style := bsSolid ;
           	Rectangle( nXOrg - nPadHeight - nColumnSpacing div 2, nYOrg - nPadWidth, nXOrg + nPadHeight - nColumnSpacing div 2 + 1, nYOrg + nPadWidth + 1 ) ;
			  	Rectangle( nXOrg - nPadHeight + nColumnSpacing div 2, nYOrg - nPadWidth, nXOrg + nPadHeight + nColumnSpacing div 2 + 1, nYOrg + nPadWidth + 1 ) ;
           end ;
           if TextHeight( '99' ) < nPinSpacing div 32000 then begin
	 			nYOrg := ShapeBox.Height div 2 ;
				Brush.Style := bsClear ;
       		for n := 0 to nPins div 4 - 1 do begin
       			nXOrg := ShapeBox.Width div 2 + ( n * nPinSpacing - ( nPins div 4 - 1 ) * nPinSpacing div 2 ) div 32000 ;
					TextOut( nXOrg + nPadWidth, nYOrg + nPadHeight + nRowSpacing div 2, IntToStr( n + 1 ) ) ;
               	TextOut( nXOrg + nPadWidth, nYOrg + nPadHeight - nRowSpacing div 2, IntToStr( 3 * nPins div 4 - n ) ) ;
				end ;
				nXOrg := ShapeBox.Width div 2 ;
       		for n := 0 to nPins div 4 - 1 do begin
       			nYOrg := ShapeBox.Height div 2 + ( n * nPinSpacing - ( nPins div 4 - 1 ) * nPinSpacing div 2 ) div 32000 ;
					TextOut( nXOrg + nPadHeight + nColumnSpacing div 2, nYOrg - nPadWidth, IntToStr( nPins div 2 - n ) ) ;
   	            TextOut( nXOrg + nPadHeight - nColumnSpacing div 2, nYOrg - nPadWidth, IntToStr( 3 * nPins div 4 + n + 1 ) ) ;
				end ;
			end ;
       end ;
   end ;
end;

procedure TMainForm.ShapeDataSourceDataChange(Sender: TObject;
  Field: TField);
var sText : string ;
begin
	with MedaxDataForm do begin
		sText := ShapeTable.FindField( 'Pad' ).AsString ;
		if PadsTable.Active then
			PadsTable.FindKey( [ sText] ) ;
		if ShapeBox.Visible then
			ShapeBox.Invalidate ;
   end ;
end;

procedure TMainForm.PartsButtonClick(Sender: TObject);
begin
  	DBPanel.Visible := PartsButton.Down ;
end;

procedure TMainForm.TreeButtonClick(Sender: TObject);
begin
	ListPanel.Visible := TreeButton.Down ;
end;

procedure TMainForm.PadsTableAfterPost(DataSet: TDataSet);
begin
	ShapeBox.Invalidate ;
end;

procedure TMainForm.TabControlChange(Sender: TObject);
begin
	MainProjectPanel.Visible := False ;
	MainDrawPanel.Visible := False ;
   MainPCBPanel.Visible := False ;
   MainMechPanel.Visible := False ;
   MainGerberPanel.Visible := False ;
   MainBoxPanel.Visible := False ;
   MainShapePanel.Visible := False ;
	case TabControl.TabIndex of
	0 : MainProjectPanel.Visible := True ;
	1 : MainDrawPanel.Visible := True ;
	2 :	MainPCBPanel.Visible := True ;
   3 :	MainMechPanel.Visible := True ;
   4 : MainGerberPanel.Visible := True ;
   5 :	MainBoxPanel.Visible := True ;
   6 : MainShapePanel.Visible := True ;
	end ;
	ProjectToolsPanel.Visible := MainProjectPanel.Visible ;
	DrawToolsPanel.Visible := MainDrawPanel.Visible ;
	PCBToolsPanel.Visible := MainPCBPanel.Visible ;
	MechToolsPanel.Visible := MainMechPanel.Visible ;
	gerberToolsPanel.Visible := MainGerberPanel.Visible ;
	BoxToolsPanel.Visible := MainBoxPanel.Visible ;
	ShapeToolsPanel.Visible := MainShapePanel.Visible ;
end;

procedure TMainForm.SplitPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var nTop : integer ;
begin
	nTop := StatusBar.Top ;
	if Shift = [ssLeft] then
   	DBPanel.Height := DBPanel.Height - Y ;
	StatusBar.Top := nTop ;
end;

procedure TMainForm.PinsSplitPanelMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
	if Shift = [ssLeft] then
   	PinsDBPanel.Width := PinsDBPanel.Width - X ;
end;

procedure TMainForm.BoxPaintBoxPaint(Sender: TObject);
var
	sLabel, sBox, sPos : string ;
	nBoxWidth, nBoxHeight : integer ;
   nPin, nPos, nTextW, nTextH : integer ;
   nXOrg, nYOrg, nZoom : integer ;
begin
	nXOrg := BoxPaintBox.Width div 2 ;
   nYOrg := BoxPaintBox.Height div 2 ;
   nZoom := BoxPaintBox.Tag ;
	with MedaxDataForm.BoxTable do begin
   	try
       	sBox := FindField( 'Box' ).AsString ;
			nBoxHeight := FindField( 'Height' ).AsInteger * nZoom div 2 ;
			nBoxWidth := FindField( 'Width' ).AsInteger * nZoom div 2 ;
       except
       	Exit ;
       end ;
   end ;
   with BoxPaintBox.Canvas do begin
       MoveTo( nXOrg, 0 ) ;
  		LineTo( nXOrg, BoxPaintBox.Height ) ;
       MoveTo( 0, nYOrg ) ;
  		LineTo( BoxPaintBox.Width, nYOrg ) ;

   	Pen.Width := nZoom div 16 ;
       Brush.Color := clWhite ;
       Pen.Color := clBlack ;
  		Rectangle( nXOrg - nBoxWidth, nYOrg - nBoxHeight, nXOrg + nBoxWidth, nYOrg + nBoxHeight ) ;

       Brush.Style := bsClear ;
       Pen.Color := clBlack ;
		Font.Color := clTeal ;
       Font.Height := - 3 * nZoom div 4 ;
   end ;
	with MedaxDataForm.PinsTable do begin
   	try
       	MedaxDataForm.PinsDataSource.Enabled := False ;
			SetRange( [ sBox ], [ sBox ] ) ;
           First ;
   		while not EOF do begin
				nPin := FindField( 'Pin' ).AsInteger * nZoom div 64 ;
				sLabel := FindField( 'Label' ).AsString ;
               sPos := FindField( 'Position' ).AsString ;
               nPos := StrToInt( Copy( sPos, 2, 8 ) ) - 1 ;
               with BoxPaintBox.Canvas do begin
					nTextH := TextHeight( sLabel ) div 2 ;
                   nTextW := TextWidth( sLabel ) ;
                   case sPos[ 1 ] of
   	            'T': begin
                   	MoveTo( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2, nYOrg - nBoxHeight ) ;
                   	LineTo( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2, nYOrg - nBoxHeight - nZoom div 2 ) ;
                      	TextOut( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2 - nTextH, nYOrg - nBoxHeight + nZoom div 8 + nTextW, sLabel ) ;
   	            	end ;
       	        'R': begin
                   	MoveTo( nXOrg + nBoxWidth,               nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 ) ;
                   	LineTo( nXOrg + nBoxWidth + nZoom div 2, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 ) ;
                      	TextOut( nXOrg + nBoxWidth - nZoom div 8 - nTextW, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 - nTextH, sLabel ) ;
   	            	end ;
           	    'B': begin
                   	MoveTo( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2, nYOrg + nBoxHeight ) ;
                   	LineTo( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2, nYOrg + nBoxHeight + nZoom div 2 ) ;
                      	TextOut( nXOrg - nBoxWidth + nPos * nZoom + nZoom div 2 - nTextH, nYOrg + nBoxHeight - nZoom div 8, sLabel ) ;
   	            	end ;
               	'L': begin
                   	MoveTo( nXOrg - nBoxWidth,               nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 ) ;
                   	LineTo( nXOrg - nBoxWidth - nZoom div 2, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 ) ;
                      	TextOut( nXOrg - nBoxWidth + nZoom div 8, nYOrg - nBoxHeight + nPos * nZoom + nZoom div 2 - nTextH, sLabel ) ;
   	            	end ;
       	        end ;
               end ;
               Next ;
           end ;
			with BoxPaintBox.Canvas do begin
				Font.Color := clMaroon ;
				TextOut( nXOrg - nBoxWidth - TextWidth( sBox ), nYOrg - nBoxHeight - TextHeight( sBox ), sBox ) ;
           end ;
       	MedaxDataForm.PinsDataSource.Enabled := True ;
       except
       	Exit ;
       end ;
   end ;
end;

procedure TMainForm.BoxDataSourceDataChange(Sender: TObject;
  Field: TField);
var sText : string ;
begin
	with MedaxDataForm do begin
		sText := BoxTable.FindField( 'Box' ).AsString ;
		if PinsTable.Active then
			PinsTable.FindKey( [ sText] ) ;
		if BoxPaintBox.Visible then
			BoxPaintBox.Invalidate ;
   end ;
end;

procedure TMainForm.PinsTableAfterPost(DataSet: TDataSet);
begin
	BoxPaintBox.Invalidate ;
end;

procedure TMainForm.BoxOpenFileBtnClick(Sender: TObject);
var IniFile : TIniFile ;
	Parts, Items : TStringList ;
	sText, sBox, sPack, sFamily : string ;
   i, j, n, p, x, y : integer ;
begin
	if BoxOpenDialog.Execute then begin
		IniFile := TIniFile.Create( BoxOpenDialog.FileName ) ;
       with IniFile do begin
       	Parts := TStringList.Create ;
       	Items := TStringList.Create ;
       	ReadSection( 'Parts', Parts ) ;
           sFamily := BoxOpenDialog.FileName ;
           while Pos( '\', sFamily ) > 0 do
	           sFamily := Copy( sFamily, Pos( '\', sFamily ) + 1, MAX_PATH ) ;
           if Pos( '.', sFamily ) > 0 then
           	Delete( sFamily, Pos( '.', sFamily ), MAX_PATH ) ;
           try
				MedaxDataForm.FamiliesTable.AppendRecord( [ sFamily ] ) ;
			except
				on EDBEngineError do
					StatusBar.Panels[ 6 ].Text := ' Key violation in Families ' ;
           end ;
			with ProgressBarHigh do begin
	         	Min := 0 ;
               Max := Parts.Count - 1 ;
           end ;
           for i := 0 to Parts.Count - 1 do begin
              	ProgressBarHigh.Position := i ;
              	sBox := ReadString( Parts.Strings[ i ], 'symbol', '' ) ;
  	            if sBox <> 'BOX' then
    	           continue ;
              	x := ReadInteger( Parts.Strings[ i ], 'xsize', 6 ) ;
              	y := ReadInteger( Parts.Strings[ i ], 'ysize', 12 ) ;
               try
		           	MedaxDataForm.BoxTable.AppendRecord( [ Parts.Strings[ i ], IntToStr( x ), IntToStr( y ) ] ) ;
               except
                  	on EDBEngineError do
                   	StatusBar.Panels[ 6 ].Text := ' Key violation in Box ' ;
               end ;
              	sPack := ReadString( Parts.Strings[ i ], 'package', '' ) ;
               if Length( sPack ) > 0 then begin
               	if Pos( ',', sPack ) > 0 then begin
                   	sBox := Copy( sPack, Pos( ',', sPack ) + 1, 80 ) ;
                       Delete( sPack, Pos( ',', sPack ), 80 ) ;
                   end else
      	               	sBox := '' ;
	    	       	try
						MedaxDataForm.PartsTable.AppendRecord( [ sFamily, Parts.Strings[ i ], Parts.Strings[ i ], null, sPack, sBox ] ) ;
					except
						on EDBEngineError do
							StatusBar.Panels[ 6 ].Text := ' Key violation in Parts ' ;
		           	end ;
               end ;
              	ReadSection( Parts.Strings[ i ], Items ) ;
               with ProgressBarLow do begin
               	Min := 0 ;
                   Max := Items.Count - 1 ;
               end ;
               for j := 0 to Items.Count - 1 do begin
               	ProgressBarLow.Position := j ;
         	     	sText := ReadString( Parts.Strings[ i ], Items.Strings[ j ], '' ) ;
                   if Copy( Items.Strings[ j ], 1, 3 ) = 'top' then begin
                   	n := StrToInt( Copy( Items.Strings[ j ], 4, 3 ) ) ;
                       p := Pos( ',', sText ) ;
						try
							MedaxDataForm.PinsTable.AppendRecord( [ Parts.Strings[ i ], Copy( sText, 1, p - 1),
                       		Copy( sText, p + 1, 16 ), '?', 'T' + IntToStr( n ) ] ) ;
               		except
         	        	 	on EDBEngineError do
     	            	  		StatusBar.Panels[ 6 ].Text := ' Key violation in Pins ' ;
	              		end ;
                   end else if Copy( Items.Strings[ j ], 1, 5 ) = 'right' then begin
                    	n := StrToInt( Copy( Items.Strings[ j ], 6, 3 ) ) ;
                       p := Pos( ',', sText ) ;
						try
							MedaxDataForm.PinsTable.AppendRecord( [ Parts.Strings[ i ], Copy( sText, 1, p - 1),
                       		Copy( sText, p + 1, 16 ), '?', 'R' + IntToStr( n ) ] ) ;
               		except
         	        	 	on EDBEngineError do
     	            	  		StatusBar.Panels[ 6 ].Text := ' Key violation in Pins ' ;
               		end ;
                  end else if Copy( Items.Strings[ j ], 1, 6 ) = 'bottom' then begin
                   	n := StrToInt( Copy( Items.Strings[ j ], 7, 3 ) ) ;
                       p := Pos( ',', sText ) ;
						try
							MedaxDataForm.PinsTable.AppendRecord( [ Parts.Strings[ i ], Copy( sText, 1, p - 1),
                       		Copy( sText, p + 1, 16 ), '?', 'B' + IntToStr( n ) ] ) ;
               		except
         	        	 	on EDBEngineError do
     	            	  		StatusBar.Panels[ 6 ].Text := ' Key violation in Pins ' ;
               		end ;
                   end else if Copy( Items.Strings[ j ], 1, 4 ) = 'left' then begin
                   	n := StrToInt( Copy( Items.Strings[ j ], 5, 3 ) ) ;
                       p := Pos( ',', sText ) ;
						try
							MedaxDataForm.PinsTable.AppendRecord( [ Parts.Strings[ i ], Copy( sText, 1, p - 1),
                       		Copy( sText, p + 1, 16 ), '?', 'L' + IntToStr( n ) ] ) ;
               		except
         	        	 	on EDBEngineError do
     	            	  		StatusBar.Panels[ 6 ].Text := ' Key violation in Pins ' ;
               		end ;
                   end ;
				end ;
               ProgressBarLow.Position := 0 ;
           end ;
           ProgressBarHigh.Position := 0 ;
           Items.Free ;
           Parts.Free ;
			Free ;
       end ;
   end ;
end;

procedure TMainForm.BoxTableBeforeDelete(DataSet: TDataSet);
begin
	with MedaxDataForm.PinsTable do begin
   	First ;
       while not EOF do
       	Delete ;
   end ;
end;

procedure TMainForm.FamiliesTableBeforeDelete(DataSet: TDataSet);
begin
	with MedaxDataForm.PartsTable do begin
   	First ;
       while not EOF do
       	Delete ;
   end ;
end;

procedure TMainForm.Panel1Click(Sender: TObject);
begin
	PCBColorDialog.Execute ;
end;

end.
